/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Control;

import BussinessLayer.MembersFactory;
import BussinessLayer.ReportsFactory;
import DTO.Member.MemberList;
import DTO.Member.Members;
import DTO.Report.ReportList;
import DTO.Report.Reports.ReportsFields;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

/**
 *
 * @author TrucTM
 */
public class Controler extends HttpServlet {

    private String homePage = "index.jsp";
    private String addnewPage = "addnew.jsp";
    private String commissionPage = "commission.jsp";
    private String viewtreePage = "viewtree.jsp";
    private String sessionCurUser = "USER";

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            String realPath = getServletContext().getRealPath("/") + "WEB-INF/";
            HttpSession session = request.getSession();
            String action = request.getParameter("btnAction");
            if (action.equals("login")) {
                String username = request.getParameter("txtUsername");
                //String password = request.getParameter("txtPassword");
                MemberList memberList = new MemberList();
                MembersFactory memberFac = new MembersFactory();
                List<Members> listMembers = new ArrayList<Members>();
                listMembers = memberFac.GetAllBy(Members.MembersFields.MemCode, username);

                memberList.setMember(listMembers);
                String url = commissionPage;//"error.jsp";
                if (memberList.getMember().size() > 0) {
                    //url = addnewPage;
                    Members member = new Members();
                    member = listMembers.get(0);
                    session.setAttribute(sessionCurUser, member);
                    session.setAttribute("REPORTURI", "WEB-INF/reports" + member.getMemCode() + ".xml");
                    session.setAttribute("MEMBERURI", "WEB-INF/members" + member.getMemCode() + ".xml");
                    genXmlFromDB(member, memberFac, realPath);
                } else {
                    url = homePage;
                    request.setAttribute("login", "false");
                }
                RequestDispatcher rd = request.getRequestDispatcher(url);
                rd.forward(request, response);
            } else if (action.equals("addNew")) {
                Members member = new Members();
                member = (Members) session.getAttribute(sessionCurUser);

                MembersFactory memberFac = new MembersFactory();
                boolean isOK = false;
                isOK = addNewMember(request, member);
                genXmlFromDB(member, memberFac, realPath);
                session.setAttribute("treeJson", getMemberTree(member, realPath));
                RequestDispatcher rd = request.getRequestDispatcher(viewtreePage);
                rd.forward(request, response);
            } else if (action.equals("view")) {
                Members member = new Members();
                member = (Members) session.getAttribute(sessionCurUser);
                session.setAttribute("treeJson", getMemberTree(member, realPath));
                RequestDispatcher rd = request.getRequestDispatcher(viewtreePage);
                rd.forward(request, response);
            } else if (action.equals("commission")) {
                RequestDispatcher rd = request.getRequestDispatcher(commissionPage);
                rd.forward(request, response);
            } else if (action.equals("add")) {
                RequestDispatcher rd = request.getRequestDispatcher(addnewPage);
                rd.forward(request, response);
            } else if (action.equals("logout")) {
                session.setAttribute("USER", null);
                RequestDispatcher rd = request.getRequestDispatcher(homePage);
                rd.forward(request, response);
            }
        } finally {
            out.close();
        }
    }

    private String getMemberTree(Members member, String realPath) {
        try {
            // read XML using JAXB
            JAXBContext jc = JAXBContext.newInstance(MemberList.class);
            Unmarshaller u = jc.createUnmarshaller();
            File f = new File(realPath + "members" + member.getMemCode() + ".xml");
            MemberList item = new MemberList();
            item = (MemberList) u.unmarshal(f);
            
            // generate JSON
            String json = "[";
            for (int i = 0; i < item.getMember().size(); i++) {
                json += "{";
                json += "MemId:\"" + item.getMember().get(i).getMemId() + "\",";
                json += "MemCode:\"" + item.getMember().get(i).getMemCode() + "\",";
                json += "FullName:\"" + item.getMember().get(i).getFullName() + "\",";
                json += "NameSpace:\"" + item.getMember().get(i).getNameSpace() + "\"";
                json += "},";
            }
            json += "]";

            json = json.replace(",]", "]");

            return json;
        } catch (JAXBException ex) {
            return "";
        }
    }

    private boolean addNewMember(HttpServletRequest request, Members curMember) {

        Members newMember = new Members();
        MembersFactory memberFactory = new MembersFactory();
        String fullname = request.getParameter("txtFullname").trim();        
        //String password = request.getParameter("txtPassword");
        String phone = request.getParameter("txtPhone").trim();
        String email = request.getParameter("txtEmail").trim();
        String address = request.getParameter("txtAddress").trim();
        String note = request.getParameter("txtNote").trim();

        //lay ID cua member truoc de khoi tao MemCode va NameSpace cho member sau
        int maxId;
        try {
            maxId = memberFactory.GetMaxId();
        } catch (Exception ex) {
            maxId = 0;
        }
        maxId += 1;
        //dung ham xoa dau tieng' viet        
        newMember.setMemCode(memberFactory.RemoveSign4VietnameseString(fullname.replace(" ", "")) + maxId);

        // lay data nhap tu user
        newMember.setFullName(fullname);
        newMember.setPhone(phone);
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        newMember.setDateReg(dateFormat.format(date));
        newMember.setEmail(email);
        newMember.setAddress(address);
        //neu la admin thi ko can` "."
        String memcode = curMember.getMemCode().toLowerCase();
        if (memcode.equals("admin")) {
            //newMember.setNameSpace(curMember.getNameSpace() + maxId);
            newMember.setNameSpace("" + maxId);
        } else {
            newMember.setNameSpace(curMember.getNameSpace().trim() + "." + maxId);
        }
        newMember.setNote(note);
        newMember.setAvaiableScore(BigInteger.ZERO);
        newMember.setHideScore(BigInteger.ZERO);
        newMember.setOriginalScore(BigInteger.valueOf(1000));
        try {
            //add member
            memberFactory = new MembersFactory();
            memberFactory.Insert(newMember);
            // tinh hh
            ReportsFactory.ComputeComission(newMember);
            return true;
        } catch (Exception ex) {
            return false;
        }
    }

    private void genXmlFromDB(Members member, MembersFactory memberFac, String realPath) {
        memberFac = new MembersFactory();
        MemberList memberList = new MemberList();        
        ReportList reportList = new ReportList();
        ReportsFactory reportFac = new ReportsFactory();
        if (member.getMemCode().toLowerCase().trim().equals("admin")) {
            memberList.setMember(memberFac.GetAll());
            reportList.setReport(reportFac.GetAll());
        } else {
            memberList.setMember(memberFac.GetNameSpace(member.getNameSpace()));
            reportList.setReport(reportFac.GetAllBy(ReportsFields.MemId_Rev, member.getMemId()));
        }
        int lenght = reportList.getReport().size();
        for (int idex = 0; idex < lenght; idex++) {
            Members newMember = new Members();
            int memRev = Integer.parseInt(reportList.getReport().get(idex).getMemIdRev().toString());
            int memSend = Integer.parseInt(reportList.getReport().get(idex).getMemIdSend().toString());
            memberFac = new MembersFactory();
            newMember = memberFac.GetByPrimaryKey(memRev);
            reportList.getReport().get(idex).setFullNameRev(newMember.getFullName().trim());
            memberFac = new MembersFactory();
            newMember = memberFac.GetByPrimaryKey(memSend);
            reportList.getReport().get(idex).setFullNameSend(newMember.getFullName().trim());
        }
        try {
            JAXBContext ctx = JAXBContext.newInstance(memberList.getClass());
            Marshaller mar = ctx.createMarshaller();
            mar.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
            mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

            mar.marshal(memberList, new File(realPath + "members" + member.getMemCode() + ".xml"));
            ctx = JAXBContext.newInstance(reportList.getClass());
            mar = ctx.createMarshaller();
            mar.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
            mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            mar.marshal(reportList, new File(realPath + "reports" + member.getMemCode() + ".xml"));
        } catch (JAXBException ex) {
        }
    }
    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">

    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}
